﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net.Http;
using Newtonsoft.Json;
using ERP_SaaS_WinForm.生产计划_派单_车间.Work;
using ERP_SaaS_WinForm.生产计划_派单_车间.apiResquest;
using ERP_SaaS_WinForm.生产工单_报工_工序;

namespace ERP_SaaS_WinForm.生产计划_派单_车间
{
    public partial class WorkOrder : Form
    {
        private string urls;
        private DataGridView dgvWorkOrders;
        private Button btnRefresh;
        private Button btnAdd;
        
        // 新增页面控件
        private TabControl tabControl;
        private TabPage tabPageList;
        private TabPage tabPageAdd;
        
        // 新增页面的输入控件
        private TextBox txtTaskCode;
        private TextBox txtTaskName;
        private TextBox txtProductId;
        private TextBox txtProductName;
        private TextBox txtSpecification;
        private TextBox txtUnitName;
        private TextBox txtMaterialId;
        private TextBox txtMaterialName;
        private TextBox txtTeamId;
        private TextBox txtTeamName;
        private TextBox txtLeader;
        private TextBox txtName;
        private TextBox txtSiteId;
        private TextBox txtSiteName;
        private TextBox txtCarId;
        private TextBox txtCarName;
        private TextBox txtLineId;
        private TextBox txtLineName;
        private ComboBox cboProcessId;
        private TextBox txtProductionOrdersId;
        private TextBox txtProductionOrdersName;
        private TextBox txtPlannedQuantity;
        private TextBox txtActualQuantity;
        private DateTimePicker dtpPlanStart;
        private DateTimePicker dtpPlanEnd;
        private DateTimePicker dtpActualStart;
        private DateTimePicker dtpActualEnd;
        
        // 选择按钮
        private Button btnSelectProduct;
        private Button btnSelectMaterial;
        private Button btnSelectTeam;
        private Button btnSelectSite;
        private Button btnSelectCar;
        private Button btnSelectLine;
        private Button btnSelectProductionOrder;

        public WorkOrder()
        {
            InitializeComponent();
            InitializeCustomComponents();
            LoadWorkOrders();
            urls = Apllo.ApiBaseUrl;
        }

        private void InitializeCustomComponents()
        {
            // 设置窗体标题
            this.Text = "工单管理";
            this.Size = new Size(1400, 800);
            this.StartPosition = FormStartPosition.CenterScreen;

            // 创建标签页控件
            tabControl = new TabControl();
            tabControl.Dock = DockStyle.Fill;

            // 创建列表页面
            tabPageList = new TabPage();
            tabPageList.Text = "工单列表";
            tabPageList.BackColor = Color.White;

            // 创建新增页面
            tabPageAdd = new TabPage();
            tabPageAdd.Text = "新增工单";
            tabPageAdd.BackColor = Color.White;

            // 创建DataGridView
            dgvWorkOrders = new DataGridView();
            dgvWorkOrders.Dock = DockStyle.Fill;
            dgvWorkOrders.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
            dgvWorkOrders.AllowUserToAddRows = false;
            dgvWorkOrders.ReadOnly = true;
            dgvWorkOrders.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
            dgvWorkOrders.MultiSelect = false;
            dgvWorkOrders.RowHeadersVisible = false;
            dgvWorkOrders.BackgroundColor = Color.White;
            dgvWorkOrders.GridColor = Color.LightGray;
            dgvWorkOrders.BorderStyle = BorderStyle.None;

            // 创建按钮
            btnRefresh = new Button();
            btnRefresh.Text = "刷新数据";
            btnRefresh.Size = new Size(100, 30);
            btnRefresh.Location = new Point(10, 10);
            btnRefresh.Click += BtnRefresh_Click;

            btnAdd = new Button();
            btnAdd.Text = "新增工单";
            btnAdd.Size = new Size(100, 30);
            btnAdd.Location = new Point(120, 10);
            btnAdd.BackColor = Color.LightGreen;
            btnAdd.Click += BtnAdd_Click;

            // 创建按钮面板
            Panel buttonPanel = new Panel();
            buttonPanel.Dock = DockStyle.Top;
            buttonPanel.Height = 50;
            buttonPanel.Controls.AddRange(new Control[] { btnRefresh, btnAdd });

            // 创建面板来容纳DataGridView
            Panel gridPanel = new Panel();
            gridPanel.Dock = DockStyle.Fill;
            gridPanel.Controls.Add(dgvWorkOrders);

            // 设置列表页面
            tabPageList.Controls.Add(gridPanel);
            tabPageList.Controls.Add(buttonPanel);

            // 设置新增页面
            CreateAddPage();

            // 添加标签页到标签控件
            tabControl.TabPages.Add(tabPageList);
            tabControl.TabPages.Add(tabPageAdd);

            // 添加标签控件到窗体
            this.Controls.Add(tabControl);
        }

        private async void LoadWorkOrders()
        {
            try
            {
                btnRefresh.Enabled = false;
                btnRefresh.Text = "加载中...";

                Console.WriteLine("开始请求工单数据...");
                var apiResponse = await ApiRequestHelper.GetAsync<ApiWorkResponse>("api/Dispatch/GetDispatch");
                
                Console.WriteLine($"API响应: Success={apiResponse.Success}, Message={apiResponse.Message}");

                if (apiResponse.Success && apiResponse.Data != null)
                {
                    var response = apiResponse.Data;
                    Console.WriteLine($"解析后的响应: code={response?.code}, msg={response?.msg}, data数量={response?.data?.Count ?? 0}");

                    if (response != null && (response.code == 200 || response.code == 0) && response.data != null)
                    {
                        Console.WriteLine($"成功获取到 {response.data.Count} 条工单数据");
                        SetupDataGridView();
                        LoadDataToGrid(response.data);
                    }
                    else
                    {
                        string errorMsg = $"获取数据失败: code={response?.code}, msg={response?.msg ?? "未知错误"}";
                        Console.WriteLine(errorMsg);
                        ApiRequestHelper.ShowError(errorMsg);
                    }
                }
                else
                {
                    string errorMsg = $"请求失败: {apiResponse.Message}";
                    Console.WriteLine(errorMsg);
                    ApiRequestHelper.ShowError(errorMsg);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"加载数据时发生异常: {ex.Message}");
                Console.WriteLine($"异常堆栈: {ex.StackTrace}");
                MessageBox.Show($"加载数据时发生错误: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                btnRefresh.Enabled = true;
                btnRefresh.Text = "刷新数据";
            }
        }

        private void SetupDataGridView()
        {
            dgvWorkOrders.Columns.Clear();

            // 添加列并设置标题
            dgvWorkOrders.Columns.Add("TaskCode", "任务编号");
            dgvWorkOrders.Columns.Add("TaskName", "任务名称");
            dgvWorkOrders.Columns.Add("ProductName", "产品名称");
            dgvWorkOrders.Columns.Add("Specification", "规格型号");
            dgvWorkOrders.Columns.Add("UnitName", "单位");
            dgvWorkOrders.Columns.Add("MaterialName", "物料名称");
            dgvWorkOrders.Columns.Add("TeamName", "班组名称");
            dgvWorkOrders.Columns.Add("Leader", "负责人");
            dgvWorkOrders.Columns.Add("Name", "成员名称");
            dgvWorkOrders.Columns.Add("SiteName", "站点名称");
            dgvWorkOrders.Columns.Add("CarName", "车间名称");
            dgvWorkOrders.Columns.Add("LineName", "生产线名称");
            dgvWorkOrders.Columns.Add("ProcessId", "工序");
            dgvWorkOrders.Columns.Add("PlannedQuantity", "计划数量");
            dgvWorkOrders.Columns.Add("ActualQuantity", "实际生产数量");
            dgvWorkOrders.Columns.Add("PlanStart", "计划开工时间");
            dgvWorkOrders.Columns.Add("PlanEnd", "计划完工时间");
            dgvWorkOrders.Columns.Add("ActualStart", "实际开工时间");
            dgvWorkOrders.Columns.Add("ActualEnd", "实际完工时间");
            

            // 设置列宽
            dgvWorkOrders.Columns["TaskCode"].Width = 80;
            dgvWorkOrders.Columns["TaskName"].Width = 80;
            dgvWorkOrders.Columns["ProductName"].Width = 80;
            dgvWorkOrders.Columns["Specification"].Width = 80;
            dgvWorkOrders.Columns["UnitName"].Width = 50;
            dgvWorkOrders.Columns["MaterialName"].Width = 80;
            dgvWorkOrders.Columns["TeamName"].Width = 80;
            dgvWorkOrders.Columns["Leader"].Width = 80;
            dgvWorkOrders.Columns["Name"].Width = 80;
            dgvWorkOrders.Columns["SiteName"].Width = 80;
            dgvWorkOrders.Columns["CarName"].Width = 80;
            dgvWorkOrders.Columns["LineName"].Width = 80;
            dgvWorkOrders.Columns["ProcessId"].Width = 50;
            dgvWorkOrders.Columns["PlannedQuantity"].Width = 50;
            dgvWorkOrders.Columns["ActualQuantity"].Width = 50;
            dgvWorkOrders.Columns["PlanStart"].Width = 150;
            dgvWorkOrders.Columns["PlanEnd"].Width = 150;
            dgvWorkOrders.Columns["ActualStart"].Width = 150;
            dgvWorkOrders.Columns["ActualEnd"].Width = 150;
            

            // 设置标题行样式
            dgvWorkOrders.ColumnHeadersDefaultCellStyle.BackColor = Color.LightBlue;
            dgvWorkOrders.ColumnHeadersDefaultCellStyle.ForeColor = Color.Black;
            dgvWorkOrders.ColumnHeadersDefaultCellStyle.Font = new Font(dgvWorkOrders.Font, FontStyle.Bold);
            dgvWorkOrders.ColumnHeadersHeight = 35;
            dgvWorkOrders.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing;

            // 设置交替行颜色
            dgvWorkOrders.AlternatingRowsDefaultCellStyle.BackColor = Color.LightGray;
        }

        private void LoadDataToGrid(List<WorkOrderData> workOrders)
        {
            dgvWorkOrders.Rows.Clear();

            foreach (var workOrder in workOrders)
            {
                int rowIndex = dgvWorkOrders.Rows.Add();
                dgvWorkOrders.Rows[rowIndex].Cells["TaskCode"].Value = workOrder.TaskCode;
                dgvWorkOrders.Rows[rowIndex].Cells["TaskName"].Value = workOrder.TaskName;
                dgvWorkOrders.Rows[rowIndex].Cells["ProductName"].Value = workOrder.ProductName;
                dgvWorkOrders.Rows[rowIndex].Cells["Specification"].Value = workOrder.Specification;
                dgvWorkOrders.Rows[rowIndex].Cells["UnitName"].Value = workOrder.UnitName;
                dgvWorkOrders.Rows[rowIndex].Cells["MaterialName"].Value = workOrder.MaterialName;
                dgvWorkOrders.Rows[rowIndex].Cells["TeamName"].Value = workOrder.TeamName;
                dgvWorkOrders.Rows[rowIndex].Cells["Leader"].Value = workOrder.Leader;
                dgvWorkOrders.Rows[rowIndex].Cells["Name"].Value = workOrder.Name;
                dgvWorkOrders.Rows[rowIndex].Cells["SiteName"].Value = workOrder.SiteName;
                dgvWorkOrders.Rows[rowIndex].Cells["CarName"].Value = workOrder.CarName;
                dgvWorkOrders.Rows[rowIndex].Cells["LineName"].Value = workOrder.LineName;
                dgvWorkOrders.Rows[rowIndex].Cells["ProcessId"].Value = GetProcessText(workOrder.ProcessId);
                dgvWorkOrders.Rows[rowIndex].Cells["PlannedQuantity"].Value = workOrder.PlannedQuantity;
                dgvWorkOrders.Rows[rowIndex].Cells["ActualQuantity"].Value = workOrder.ActualQuantity;
                dgvWorkOrders.Rows[rowIndex].Cells["PlanStart"].Value = FormatDateTime(workOrder.PlanStart);
                dgvWorkOrders.Rows[rowIndex].Cells["PlanEnd"].Value = FormatDateTime(workOrder.PlanEnd);
                dgvWorkOrders.Rows[rowIndex].Cells["ActualStart"].Value = FormatDateTime(workOrder.ActualStart);
                dgvWorkOrders.Rows[rowIndex].Cells["ActualEnd"].Value = FormatDateTime(workOrder.ActualEnd);
               
            }
        }

     

        private string GetProcessText(int processId)
        {
            switch (processId)
            {
                case 1: return "工序一";
                case 2: return "工序二";
                case 3: return "工序三";
                case 4: return "工序四";
                default: return $"工序{processId}";
            }
        }

        /// <summary>
        /// 格式化日期时间显示
        /// </summary>
        /// <param name="dateTime">日期时间</param>
        /// <returns>格式化后的字符串</returns>
        private string FormatDateTime(DateTime? dateTime)
        {
            if (dateTime.HasValue && dateTime.Value != DateTime.MinValue)
            {
                return dateTime.Value.ToString("yyyy-MM-dd HH:mm");
            }
            return "-";
        }

        /// <summary>
        /// 创建新增页面
        /// </summary>
        private void CreateAddPage()
        {
            // 创建滚动面板
            Panel scrollPanel = new Panel();
            scrollPanel.Dock = DockStyle.Fill;
            scrollPanel.AutoScroll = true;

            // 创建输入面板
            Panel inputPanel = new Panel();
            inputPanel.Dock = DockStyle.Top;
            inputPanel.Height = 650;
            inputPanel.BackColor = Color.LightGray;

            // 创建输入控件
            CreateInputControls(inputPanel);

            // 创建按钮面板
            Panel buttonPanel = new Panel();
            buttonPanel.Dock = DockStyle.Bottom;
            buttonPanel.Height = 60;
            buttonPanel.BackColor = Color.White;

            // 创建按钮
            Button btnSave = new Button();
            btnSave.Text = "保存";
            btnSave.Size = new Size(100, 35);
            btnSave.Location = new Point(20, 12);
            btnSave.BackColor = Color.LightGreen;
            btnSave.Click += BtnSave_Click;

            Button btnClear = new Button();
            btnClear.Text = "清空";
            btnClear.Size = new Size(100, 35);
            btnClear.Location = new Point(140, 12);
            btnClear.BackColor = Color.LightYellow;
            btnClear.Click += BtnClear_Click;

            Button btnCancel = new Button();
            btnCancel.Text = "取消";
            btnCancel.Size = new Size(100, 35);
            btnCancel.Location = new Point(260, 12);
            btnCancel.BackColor = Color.LightGray;
            btnCancel.Click += BtnCancel_Click;

            // 添加按钮到面板
            buttonPanel.Controls.AddRange(new Control[] { btnSave, btnClear, btnCancel });

            // 添加控件到滚动面板
            scrollPanel.Controls.Add(inputPanel);
            scrollPanel.Controls.Add(buttonPanel);

            // 添加滚动面板到新增页面
            tabPageAdd.Controls.Add(scrollPanel);
        }

        /// <summary>
        /// 创建输入控件
        /// </summary>
        private void CreateInputControls(Panel panel)
        {
            int labelX = 20;
            int textBoxX = 120;
            int startY = 20;
            int spacing = 35;

            // 第一行：任务编号、任务名称
            CreateLabelAndTextBox(panel, "任务编号:", "txtTaskCode", labelX, startY, textBoxX, startY);
            CreateLabelAndTextBox(panel, "任务名称:", "txtTaskName", labelX + 400, startY, textBoxX + 400, startY);

            // 第二行：产品外键、产品名称
            CreateLabelAndTextBox(panel, "产品外键:", "txtProductId", labelX, startY + spacing, textBoxX, startY + spacing, true);
            CreateLabelAndTextBox(panel, "产品名称:", "txtProductName", labelX + 400, startY + spacing, textBoxX + 400, startY + spacing, true);

            // 第三行：规格型号、单位
            CreateLabelAndTextBox(panel, "规格型号:", "txtSpecification", labelX, startY + spacing * 2, textBoxX, startY + spacing * 2, false, true);
            CreateLabelAndTextBox(panel, "单位:", "txtUnitName", labelX + 400, startY + spacing * 2, textBoxX + 400, startY + spacing * 2, false, true);

            // 第四行：物料外键、物料名称
            CreateLabelAndTextBox(panel, "物料外键:", "txtMaterialId", labelX, startY + spacing * 3, textBoxX, startY + spacing * 3, true);
            CreateLabelAndTextBox(panel, "物料名称:", "txtMaterialName", labelX + 400, startY + spacing * 3, textBoxX + 400, startY + spacing * 3, false, true);

            // 第五行：班组外键、班组名称
            CreateLabelAndTextBox(panel, "班组外键:", "txtTeamId", labelX, startY + spacing * 4, textBoxX, startY + spacing * 4, true);
            CreateLabelAndTextBox(panel, "班组名称:", "txtTeamName", labelX + 400, startY + spacing * 4, textBoxX + 400, startY + spacing * 4, false, true);

            // 第六行：负责人、成员名称
            CreateLabelAndTextBox(panel, "负责人:", "txtLeader", labelX, startY + spacing * 5, textBoxX, startY + spacing * 5);
            CreateLabelAndTextBox(panel, "成员名称:", "txtName", labelX + 400, startY + spacing * 5, textBoxX + 400, startY + spacing * 5);

            // 第七行：站点外键、站点名称
            CreateLabelAndTextBox(panel, "站点外键:", "txtSiteId", labelX, startY + spacing * 6, textBoxX, startY + spacing * 6, true);
            CreateLabelAndTextBox(panel, "站点名称:", "txtSiteName", labelX + 400, startY + spacing * 6, textBoxX + 400, startY + spacing * 6, false, true);

            // 第八行：车间外键、车间名称
            CreateLabelAndTextBox(panel, "车间外键:", "txtCarId", labelX, startY + spacing * 7, textBoxX, startY + spacing * 7, true);
            CreateLabelAndTextBox(panel, "车间名称:", "txtCarName", labelX + 400, startY + spacing * 7, textBoxX + 400, startY + spacing * 7, false, true);

            // 第九行：生产线外键、生产线名称
            CreateLabelAndTextBox(panel, "生产线外键:", "txtLineId", labelX, startY + spacing * 8, textBoxX, startY + spacing * 8, true);
            CreateLabelAndTextBox(panel, "生产线名称:", "txtLineName", labelX + 400, startY + spacing * 8, textBoxX + 400, startY + spacing * 8, false, true);

            // 第十行：工序、生产工单外键
            CreateLabelAndComboBox(panel, "工序:", "cboProcessId", labelX, startY + spacing * 9, textBoxX, startY + spacing * 9);
            CreateLabelAndTextBox(panel, "生产工单外键:", "txtProductionOrdersId", labelX + 400, startY + spacing * 9, textBoxX + 400, startY + spacing * 9, true);

            // 第十一行：生产工单名称、计划数量
            CreateLabelAndTextBox(panel, "生产工单名称:", "txtProductionOrdersName", labelX, startY + spacing * 10, textBoxX, startY + spacing * 10, false, true);
            CreateLabelAndTextBox(panel, "计划数量:", "txtPlannedQuantity", labelX + 400, startY + spacing * 10, textBoxX + 400, startY + spacing * 10);

            // 第十二行：实际生产数量、任务状态
            CreateLabelAndTextBox(panel, "实际生产数量:", "txtActualQuantity", labelX, startY + spacing * 11, textBoxX, startY + spacing * 11);
            CreateLabelAndDateTimePicker(panel, "计划开工时间:", "dtpPlanStart", labelX, startY + spacing * 12, textBoxX, startY + spacing * 12);

            // 第十三行：计划完工时间、实际开工时间
            CreateLabelAndDateTimePicker(panel, "计划完工时间:", "dtpPlanEnd", labelX + 400, startY + spacing * 12, textBoxX + 400, startY + spacing * 12);
            CreateLabelAndDateTimePicker(panel, "实际开工时间:", "dtpActualStart", labelX, startY + spacing * 13, textBoxX, startY + spacing * 13);

            // 第十四行：实际完工时间
            CreateLabelAndDateTimePicker(panel, "实际完工时间:", "dtpActualEnd", labelX + 400, startY + spacing * 13, textBoxX + 400, startY + spacing * 13);


        }

        /// <summary>
        /// 创建标签和文本框
        /// </summary>
        private void CreateLabelAndTextBox(Panel panel, string labelText, string textBoxName, int labelX, int labelY, int textBoxX, int textBoxY, bool hasSelectButton = false, bool isReadOnly = false)
        {
            // 创建标签
            Label label = new Label();
            label.Text = labelText;
            label.Location = new Point(labelX, labelY);
            label.Size = new Size(80, 20);

            // 创建文本框
            TextBox textBox = new TextBox();
            textBox.Name = textBoxName;
            textBox.Location = new Point(textBoxX, textBoxY);
            textBox.Size = new Size(150, 20);
            textBox.ReadOnly = isReadOnly;

            // 根据名称设置对应的字段
            switch (textBoxName)
            {
                case "txtTaskCode": txtTaskCode = textBox; break;
                case "txtTaskName": txtTaskName = textBox; break;
                case "txtProductId": txtProductId = textBox; break;
                case "txtProductName": txtProductName = textBox; break;
                case "txtSpecification": txtSpecification = textBox; break;
                case "txtUnitName": txtUnitName = textBox; break;
                case "txtMaterialId": txtMaterialId = textBox; break;
                case "txtMaterialName": txtMaterialName = textBox; break;
                case "txtTeamId": txtTeamId = textBox; break;
                case "txtTeamName": txtTeamName = textBox; break;
                case "txtLeader": txtLeader = textBox; break;
                case "txtName": txtName = textBox; break;
                case "txtSiteId": txtSiteId = textBox; break;
                case "txtSiteName": txtSiteName = textBox; break;
                case "txtCarId": txtCarId = textBox; break;
                case "txtCarName": txtCarName = textBox; break;
                case "txtLineId": txtLineId = textBox; break;
                case "txtLineName": txtLineName = textBox; break;
                case "txtProductionOrdersId": txtProductionOrdersId = textBox; break;
                case "txtProductionOrdersName": txtProductionOrdersName = textBox; break;
                case "txtPlannedQuantity": txtPlannedQuantity = textBox; break;
                case "txtActualQuantity": txtActualQuantity = textBox; break;
            }

            // 添加控件到面板
            panel.Controls.Add(label);
            panel.Controls.Add(textBox);

            // 如果需要选择按钮
            if (hasSelectButton)
            {
                Button selectButton = new Button();
                selectButton.Text = "...";
                selectButton.Size = new Size(30, 20);
                selectButton.Location = new Point(textBoxX + 160, textBoxY);
                selectButton.Click += (sender, e) => SelectButton_Click(sender, e, textBoxName);

                // 根据名称设置对应的按钮字段
                switch (textBoxName)
                {
                    case "txtProductId": btnSelectProduct = selectButton; break;
                    case "txtMaterialId": btnSelectMaterial = selectButton; break;
                    case "txtTeamId": btnSelectTeam = selectButton; break;
                    case "txtSiteId": btnSelectSite = selectButton; break;
                    case "txtCarId": btnSelectCar = selectButton; break;
                    case "txtLineId": btnSelectLine = selectButton; break;
                    case "txtProductionOrdersId": btnSelectProductionOrder = selectButton; break;
                }

                panel.Controls.Add(selectButton);
            }
        }

        /// <summary>
        /// 创建标签和下拉框
        /// </summary>
        private void CreateLabelAndComboBox(Panel panel, string labelText, string comboBoxName, int labelX, int labelY, int comboBoxX, int comboBoxY)
        {
            // 创建标签
            Label label = new Label();
            label.Text = labelText;
            label.Location = new Point(labelX, labelY);
            label.Size = new Size(80, 20);

            // 创建下拉框
            ComboBox comboBox = new ComboBox();
            comboBox.Name = comboBoxName;
            comboBox.Location = new Point(comboBoxX, comboBoxY);
            comboBox.Size = new Size(150, 20);
            comboBox.DropDownStyle = ComboBoxStyle.DropDownList;

            // 设置工序选项
            if (comboBoxName == "cboProcessId")
            {
                comboBox.Items.AddRange(new object[] { "请选择", "工序一", "工序二", "工序三", "工序四" });
                comboBox.SelectedIndex = 0;
                cboProcessId = comboBox;
            }

            // 添加控件到面板
            panel.Controls.Add(label);
            panel.Controls.Add(comboBox);
        }

        /// <summary>
        /// 创建标签和日期时间选择器
        /// </summary>
        private void CreateLabelAndDateTimePicker(Panel panel, string labelText, string dateTimePickerName, int labelX, int labelY, int dateTimePickerX, int dateTimePickerY)
        {
            // 创建标签
            Label label = new Label();
            label.Text = labelText;
            label.Location = new Point(labelX, labelY);
            label.Size = new Size(80, 20);

            // 创建日期时间选择器
            DateTimePicker dateTimePicker = new DateTimePicker();
            dateTimePicker.Name = dateTimePickerName;
            dateTimePicker.Location = new Point(dateTimePickerX, dateTimePickerY);
            dateTimePicker.Size = new Size(150, 20);
            dateTimePicker.Format = DateTimePickerFormat.Custom;
            dateTimePicker.CustomFormat = "yyyy-MM-dd HH:mm";

            // 根据名称设置对应的字段
            switch (dateTimePickerName)
            {
                case "dtpPlanStart": dtpPlanStart = dateTimePicker; break;
                case "dtpPlanEnd": dtpPlanEnd = dateTimePicker; break;
                case "dtpActualStart": dtpActualStart = dateTimePicker; break;
                case "dtpActualEnd": dtpActualEnd = dateTimePicker; break;
            }

            // 添加控件到面板
            panel.Controls.Add(label);
            panel.Controls.Add(dateTimePicker);
        }

        /// <summary>
        /// 新增工单按钮点击事件
        /// </summary>
        private void BtnAdd_Click(object sender, EventArgs e)
        {
            tabControl.SelectedTab = tabPageAdd;
        }

        /// <summary>
        /// 保存按钮点击事件
        /// </summary>
        private async void BtnSave_Click(object sender, EventArgs e)
        {
            try
            {
                // 验证必填字段
                if (string.IsNullOrWhiteSpace(txtTaskCode.Text))
                {
                    MessageBox.Show("请输入任务编号", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    txtTaskCode.Focus();
                    return;
                }

                if (string.IsNullOrWhiteSpace(txtTaskName.Text))
                {
                    MessageBox.Show("请输入任务名称", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    txtTaskName.Focus();
                    return;
                }

                // 创建WorkOrderData对象
                var workOrderData = new WorkOrderData
                {
                    TaskCode = txtTaskCode.Text.Trim(),
                    TaskName = txtTaskName.Text.Trim(),
                    ProductId = int.TryParse(txtProductId.Text, out int productId) ? productId : 0,
                    ProductName = txtProductName.Text.Trim(),
                    Specification = txtSpecification.Text.Trim(),
                    UnitName = txtUnitName.Text.Trim(),
                    MaterialId = int.TryParse(txtMaterialId.Text, out int materialId) ? materialId : 0,
                    MaterialName = txtMaterialName.Text.Trim(),
                    TeamId = int.TryParse(txtTeamId.Text, out int teamId) ? teamId : 0,
                    TeamName = txtTeamName.Text.Trim(),
                    Leader = txtLeader.Text.Trim(),
                    Name = txtName.Text.Trim(),
                    SiteId = int.TryParse(txtSiteId.Text, out int siteId) ? siteId : 0,
                    SiteName = txtSiteName.Text.Trim(),
                    CarId = int.TryParse(txtCarId.Text, out int carId) ? carId : 0,
                    CarName = txtCarName.Text.Trim(),
                    LineId = int.TryParse(txtLineId.Text, out int lineId) ? lineId : 0,
                    LineName = txtLineName.Text.Trim(),
                    ProcessId = cboProcessId.SelectedIndex > 0 ? cboProcessId.SelectedIndex : 0,
                    ProductionOrdersId = int.TryParse(txtProductionOrdersId.Text, out int productionOrdersId) ? productionOrdersId : 0,
                    PlannedQuantity = int.TryParse(txtPlannedQuantity.Text, out int plannedQuantity) ? plannedQuantity : 0,
                    ActualQuantity = int.TryParse(txtActualQuantity.Text, out int actualQuantity) ? actualQuantity : 0,
                    PlanStart = dtpPlanStart.Value,
                    PlanEnd = dtpPlanEnd.Value,
                    ActualStart = dtpActualStart.Value,
                    ActualEnd = dtpActualEnd.Value,
                  
                };

                // 发送POST请求
                var apiResponse = await ApiRequestHelper.PostAsync<ApiAddWorkResponse>("api/Dispatch/AddDispatch", workOrderData);

                if (apiResponse.Success && apiResponse.Data != null && apiResponse.Data.code == 200)
                {
                    ApiRequestHelper.ShowSuccess("工单添加成功！");
                    
                    // 工单添加成功后，自动生成/更新生产工单（存在则修改，不存在则新增）
                    try
                    {
                        await UpsertProductionOrderFromWorkOrderAsync(workOrderData);
                    }
                    catch (Exception exGen)
                    {
                        // 不中断主流程，仅提示
                        Console.WriteLine($"根据工单生成生产工单失败: {exGen.Message}");
                        ApiRequestHelper.ShowWarning($"工单添加成功！\n但生产工单生成失败: {exGen.Message}\n\n请检查网络连接或联系管理员。");
                    }
                    
                    ClearInputs();
                    tabControl.SelectedTab = tabPageList;
                    LoadWorkOrders(); // 刷新数据
                }
                else
                {
                    string errorMsg = apiResponse.Success ? 
                        $"添加失败: {apiResponse.Data?.msg ?? "未知错误"}" : 
                        $"请求失败: {apiResponse.Message}";
                    ApiRequestHelper.ShowError(errorMsg);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"添加工单时发生错误: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        /// <summary>
        /// 清空按钮点击事件
        /// </summary>
        private void BtnClear_Click(object sender, EventArgs e)
        {
            ClearInputs();
        }

        /// <summary>
        /// 取消按钮点击事件
        /// </summary>
        private void BtnCancel_Click(object sender, EventArgs e)
        {
            tabControl.SelectedTab = tabPageList;
        }

        /// <summary>
        /// 清空输入框
        /// </summary>
        private void ClearInputs()
        {
            txtTaskCode.Clear();
            txtTaskName.Clear();
            txtProductId.Clear();
            txtProductName.Clear();
            txtSpecification.Clear();
            txtUnitName.Clear();
            txtMaterialId.Clear();
            txtMaterialName.Clear();
            txtTeamId.Clear();
            txtTeamName.Clear();
            txtLeader.Clear();
            txtName.Clear();
            txtSiteId.Clear();
            txtSiteName.Clear();
            txtCarId.Clear();
            txtCarName.Clear();
            txtLineId.Clear();
            txtLineName.Clear();
            txtProductionOrdersId.Clear();
            txtProductionOrdersName.Clear();
            txtPlannedQuantity.Clear();
            txtActualQuantity.Clear();
            
            if (cboProcessId.Items.Count > 0)
                cboProcessId.SelectedIndex = 0;
            
            dtpPlanStart.Value = DateTime.Now;
            dtpPlanEnd.Value = DateTime.Now.AddDays(1);
            dtpActualStart.Value = DateTime.Now;
            dtpActualEnd.Value = DateTime.Now.AddDays(1);
            
            txtTaskCode.Focus();
        }

        /// <summary>
        /// 选择按钮点击事件
        /// </summary>
        private void SelectButton_Click(object sender, EventArgs e, string textBoxName)
        {
            try
            {
                switch (textBoxName)
                {
                    case "txtProductId":
                        OpenSelectProduct();
                        break;
                    case "txtMaterialId":
                        OpenSelectMaterial();
                        break;
                    case "txtTeamId":
                        OpenSelectTeam();
                        break;
                    case "txtSiteId":
                        OpenSelectSite();
                        break;
                    case "txtCarId":
                        OpenSelectCar();
                        break;
                    case "txtLineId":
                        OpenSelectLine();
                        break;
                    case "txtProductionOrdersId":
                        OpenSelectProductionOrder();
                        break;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"打开选择窗口失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        /// <summary>
        /// 打开产品选择窗口
        /// </summary>
        private void OpenSelectProduct()
        {
            var selectProductForm = new SelectProduct();
            if (selectProductForm.ShowDialog() == DialogResult.OK)
            {
                if (selectProductForm.SelectedProduct != null)
                {
                    var product = selectProductForm.SelectedProduct;
                    txtProductId.Text = product.ProductId.ToString();
                    txtProductName.Text = product.ProductName ?? "";
                    txtSpecification.Text = product.Specification ?? "";
                    txtUnitName.Text = product.UnitName ?? "";
                }
            }
        }

        /// <summary>
        /// 打开物料选择窗口
        /// </summary>
        private void OpenSelectMaterial()
        {
            var selectMaterialForm = new SelectMaterial();
            if (selectMaterialForm.ShowDialog() == DialogResult.OK)
            {
                if (selectMaterialForm.SelectedMaterial != null)
                {
                    var material = selectMaterialForm.SelectedMaterial;
                    txtMaterialId.Text = material.MaterialId.ToString();
                    txtMaterialName.Text = material.MaterialName ?? "";
                }
            }
        }

        /// <summary>
        /// 打开班组选择窗口
        /// </summary>
        private void OpenSelectTeam()
        {
            var selectTeamForm = new SelectTeam();
            if (selectTeamForm.ShowDialog() == DialogResult.OK)
            {
                if (selectTeamForm.SelectedTeam != null)
                {
                    var team = selectTeamForm.SelectedTeam;
                    txtTeamId.Text = team.TeamCode ?? "";
                    txtTeamName.Text = team.TeamName ?? "";
                    txtLeader.Text = team.Leader ?? "";
                    txtName.Text = team.Name ?? "";
                }
            }
        }

        /// <summary>
        /// 打开站点选择窗口
        /// </summary>
        private void OpenSelectSite()
        {
            var selectSiteForm = new SelectSite();
            if (selectSiteForm.ShowDialog() == DialogResult.OK)
            {
                if (selectSiteForm.SelectedSite != null)
                {
                    var site = selectSiteForm.SelectedSite;
                    txtSiteId.Text = site.SiteCode ?? "";
                    txtSiteName.Text = site.SiteName ?? "";
                }
            }
        }

        /// <summary>
        /// 打开车间选择窗口
        /// </summary>
        private void OpenSelectCar()
        {
            var selectCarForm = new SelectCar();
            if (selectCarForm.ShowDialog() == DialogResult.OK)
            {
                if (selectCarForm.SelectedCar != null)
                {
                    var car = selectCarForm.SelectedCar;
                    txtCarId.Text = car.CarCode ?? "";
                    txtCarName.Text = car.CarName ?? "";
                }
            }
        }

        /// <summary>
        /// 打开生产线选择窗口
        /// </summary>
        private void OpenSelectLine()
        {
            var selectLineForm = new SelectLine();
            if (selectLineForm.ShowDialog() == DialogResult.OK)
            {
                if (selectLineForm.SelectedLine != null)
                {
                    var line = selectLineForm.SelectedLine;
                    txtLineId.Text = line.LineCode ?? "";
                    txtLineName.Text = line.LineName ?? "";
                }
            }
        }

        /// <summary>
        /// 打开生产工单选择窗口
        /// </summary>
        private void OpenSelectProductionOrder()
        {
            var selectProductionOrderForm = new SelectProductionOrder();
            if (selectProductionOrderForm.ShowDialog() == DialogResult.OK)
            {
                if (selectProductionOrderForm.SelectedProductionOrder != null)
                {
                    var productionOrder = selectProductionOrderForm.SelectedProductionOrder;
                    
                    // 回显生产工单基本信息
                    txtProductionOrdersId.Text = productionOrder.ProductionOrdersCode ?? "";
                    txtProductionOrdersName.Text = productionOrder.ProductionOrdersName ?? "";
                    
                    // 回显数量信息
                    txtPlannedQuantity.Text = productionOrder.PlannedQuantity.ToString();
                    txtActualQuantity.Text = productionOrder.ActualQuantity.ToString();
                    
                    // 回显时间信息
                    if (productionOrder.PlanStart.HasValue)
                    {
                        dtpPlanStart.Value = productionOrder.PlanStart.Value;
                    }
                    
                    if (productionOrder.PlanEnd.HasValue)
                    {
                        dtpPlanEnd.Value = productionOrder.PlanEnd.Value;
                    }
                    
                    if (productionOrder.ActualStart.HasValue)
                    {
                        dtpActualStart.Value = productionOrder.ActualStart.Value;
                    }
                    
                    if (productionOrder.ActualEnd.HasValue)
                    {
                        dtpActualEnd.Value = productionOrder.ActualEnd.Value;
                    }
                }
            }
        }

        private void BtnRefresh_Click(object sender, EventArgs e)
        {
            LoadWorkOrders();
        }

        /// <summary>
        /// 新增或更新生产工单（按工单编号存在性判断）
        /// </summary>
        private async Task UpsertProductionOrderFromWorkOrderAsync(WorkOrderData workOrder)
        {
            if (workOrder == null) return;

            // 优先使用用户在“生产工单外键”里选择/填写的编号；否则生成一个新编号
            string inputCode = (txtProductionOrdersId?.Text ?? string.Empty).Trim();
            string productionOrderCode = string.IsNullOrWhiteSpace(inputCode)
                ? (await GetNextProductionOrderCodeAsync() ?? ("GDBH" + DateTime.Now.ToString("MMddHHmm")))
                : inputCode;

            // 1) 查询该编号是否已经存在
            var existing = await FindProductionOrderByCodeAsync(productionOrderCode);

            if (existing == null)
            {
                // 2a) 不存在 → 走新增
                await CreateProductionOrderFromWorkOrderAsync(workOrder, productionOrderCode);
                return;
            }

            // 2b) 已存在 → 走修改（保留后端必填的原有字段）
            try
            {
                var payload = new
                {
                    // 必填主键与编号
                    ProductionOrdersId = (int)(existing.productionOrdersId ?? existing.ProductionOrdersId),
                    ProductionOrdersCode = productionOrderCode,
                    // 名称/计划等从当前工单更新
                    ProductionOrdersName = workOrder.TaskName ?? (string)(existing.productionOrdersName ?? existing.ProductionOrdersName ?? "生产工单"),
                    PlannedQuantity = workOrder.PlannedQuantity,
                    PlanStart = (workOrder.PlanStart ?? DateTime.Now).ToString("yyyy-MM-ddTHH:mm:ss"),
                    PlanEnd = (workOrder.PlanEnd ?? DateTime.Now.AddDays(1)).ToString("yyyy-MM-ddTHH:mm:ss"),
                    DemandDate = (workOrder.PlanEnd ?? DateTime.Now.AddDays(1)).ToString("yyyy-MM-ddTHH:mm:ss"),
                    ActualStart = (existing.actualStart ?? existing.ActualStart)?.ToString("yyyy-MM-ddTHH:mm:ss") ?? "",
                    ActualEnd = (string)null,
                    ActualQuantity = workOrder.ActualQuantity,
                    ProductionOrdersProgress = (int)(existing.productionOrdersProgress ?? existing.ProductionOrdersProgress ?? 0),
                    State = 0,
                    Remark = $"基于工单 {workOrder.TaskCode} 更新",
                    CreateBy = !string.IsNullOrWhiteSpace(Environment.UserName) ? Environment.UserName : "System",
                    // 其余从已存在工单拷贝，满足接口必填
                    BOM = (string)(existing.bom ?? existing.BOM ?? ("BOM" + DateTime.Now.ToString("yyyyMMddHHmmss"))),
                    Type = (string)(existing.type ?? existing.Type ?? "工单生成"),
                    Unit = (string)(existing.unit ?? existing.Unit ?? workOrder.UnitName ?? ""),
                    Version = (string)(existing.version ?? existing.Version ?? "1.0"),
                    PlanNumber = (string)(existing.planNumber ?? existing.PlanNumber ?? workOrder.TaskCode ?? ""),
                    ProductCode = (string)(existing.productCode ?? existing.ProductCode ?? workOrder.ProductId.ToString()),
                    ProductName = (string)(existing.productName ?? existing.ProductName ?? workOrder.ProductName ?? ""),
                    ProductType = (string)(existing.productType ?? existing.ProductType ?? "成品"),
                    AssociatePlans = (string)(existing.associatePlans ?? existing.AssociatePlans ?? workOrder.TaskCode ?? ""),
                    SpecificationModel = (string)(existing.specificationModel ?? existing.SpecificationModel ?? workOrder.Specification ?? ""),
                    Batch = (string)(existing.batch ?? existing.Batch ?? DateTime.Now.ToString("yyyyMMddHHmmss"))
                };

                using (var http = new HttpClient())
                {
                    var content = new StringContent(JsonConvert.SerializeObject(payload), Encoding.UTF8, "application/json");
                    var resp = await http.PostAsync(urls+"/api/ProductionOrders/Handle", content);
                    var txt = await resp.Content.ReadAsStringAsync();
                    if (!resp.IsSuccessStatusCode)
                    {
                        throw new Exception($"HTTP {resp.StatusCode}: {txt}");
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"更新生产工单失败: {ex.Message}");
                throw;
            }
        }

        /// <summary>
        /// 按编号查找生产工单（返回动态对象，兼容不同大小写字段）
        /// </summary>
        private async Task<dynamic> FindProductionOrderByCodeAsync(string productionOrderCode)
        {
            try
            {
                using (var http = new HttpClient())
                {
                    for (int page = 1; page <= 10; page++)
                    {
                        var url = urls+$"/api/ProductionOrders/ProductionOrdersCommand?PageIndex={page}&PageSize=100";
                        var resp = await http.GetAsync(url);
                        if (!resp.IsSuccessStatusCode) break;
                        var json = await resp.Content.ReadAsStringAsync();
                        dynamic root = JsonConvert.DeserializeObject(json);
                        var arr = root?.data?.pageDatas ?? root?.data?.data;
                        if (arr == null) break;
                        foreach (var it in arr)
                        {
                            string code = (string)(it["productionOrdersCode"] ?? it["ProductionOrdersCode"]);
                            if (string.Equals(code, productionOrderCode, StringComparison.OrdinalIgnoreCase))
                            {
                                return it;
                            }
                        }
                        if ((int)(root?.data?.totalPage ?? 1) <= page) break;
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"查询生产工单失败: {ex.Message}");
            }
            return null;
        }

        /// <summary>
        /// 根据工单数据生成生产工单
        /// </summary>
        private async Task CreateProductionOrderFromWorkOrderAsync(WorkOrderData workOrder, string specifiedCode = null)
        {
            if (workOrder == null) return;

            try
            {
                // 生成/使用工单编号：优先使用指定编号；否则按 GDBH#### 递增；若失败回退为时间戳
                string nextCode = specifiedCode;
                if (string.IsNullOrWhiteSpace(nextCode))
                {
                    nextCode = await GetNextProductionOrderCodeAsync();
                    if (string.IsNullOrWhiteSpace(nextCode))
                    {
                        nextCode = "GDBH" + DateTime.Now.ToString("MMddHHmm");
                    }
                }

                var payload = new
                {
                    // 基本字段
                    ProductionOrdersCode = nextCode,
                    ProductionOrdersName = workOrder.TaskName ?? "新生产工单",
                    ProductionOrdersProgress = 0,
                    AssociatePlans = workOrder.TaskCode ?? string.Empty,
                    PlanNumber = workOrder.TaskCode ?? string.Empty,
                    Type = "工单生成",
                    ProductName = workOrder.ProductName ?? string.Empty,
                    ProductCode = workOrder.ProductId.ToString(),
                    SpecificationModel = workOrder.Specification ?? string.Empty,
                    ProductType = "成品",
                    Unit = workOrder.UnitName ?? string.Empty,
                    BOM = "BOM" + DateTime.Now.ToString("yyyyMMddHHmmss"),
                    Version = "1.0",
                    PlannedQuantity = workOrder.PlannedQuantity,
                    ActualQuantity = workOrder.ActualQuantity,
                    PlanStart = workOrder.PlanStart?.ToString("yyyy-MM-ddTHH:mm:ss") ?? DateTime.Now.ToString("yyyy-MM-ddTHH:mm:ss"),
                    PlanEnd = workOrder.PlanEnd?.ToString("yyyy-MM-ddTHH:mm:ss") ?? DateTime.Now.AddDays(1).ToString("yyyy-MM-ddTHH:mm:ss"),
                    DemandDate = workOrder.PlanEnd?.ToString("yyyy-MM-ddTHH:mm:ss") ?? DateTime.Now.AddDays(1).ToString("yyyy-MM-ddTHH:mm:ss"),
                    Batch = DateTime.Now.ToString("yyyyMMddHHmmss"),
                    ActualStart = workOrder.ActualStart?.ToString("yyyy-MM-ddTHH:mm:ss") ?? DateTime.Now.ToString("yyyy-MM-ddTHH:mm:ss"),
                    ActualEnd = (string)null,
                    Remark = $"基于工单 {workOrder.TaskCode} 生成",
                    State = 0,
                    CreateBy = !string.IsNullOrWhiteSpace(Environment.UserName) ? Environment.UserName : "System"
                };

                var json = JsonConvert.SerializeObject(payload);
                using (var http = new HttpClient())
                {
                    var content = new StringContent(json, Encoding.UTF8, "application/json");
                    var resp = await http.PostAsync(urls+"/api/ProductionOrders/AddProductionOrdersCommand", content);
                    var txt = await resp.Content.ReadAsStringAsync();
                    
                    if (!resp.IsSuccessStatusCode)
                    {
                        throw new Exception($"HTTP {resp.StatusCode}: {txt}");
                    }
                    
                    Console.WriteLine("生产工单创建成功");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"创建生产工单失败: {ex.Message}");
                throw;
            }
        }

        /// <summary>
        /// 获取下一个生产工单编号
        /// </summary>
        private async Task<string> GetNextProductionOrderCodeAsync()
        {
            try
            {
                using (var http = new HttpClient())
                {
                    // 取较大的 PageSize 以便尽可能拿到最新的编号
                    var url = urls+"/api/ProductionOrders/ProductionOrdersCommand?PageIndex=1&PageSize=200";
                    var resp = await http.GetAsync(url);
                    resp.EnsureSuccessStatusCode();
                    var json = await resp.Content.ReadAsStringAsync();
                    dynamic root = JsonConvert.DeserializeObject(json);
                    var arr = root?.data?.pageDatas ?? root?.data?.data;
                    int maxNo = 0;
                    if (arr != null)
                    {
                        foreach (var it in arr)
                        {
                            string code = (string)(it["productionOrdersCode"] ?? it["ProductionOrdersCode"]);
                            if (string.IsNullOrWhiteSpace(code)) continue;
                            if (code.StartsWith("GDBH", StringComparison.OrdinalIgnoreCase))
                            {
                                var numPart = new string(code.Skip(4).Where(char.IsDigit).ToArray());
                                if (int.TryParse(numPart, out int n))
                                {
                                    if (n > maxNo) maxNo = n;
                                }
                            }
                        }
                    }
                    int next = maxNo + 1;
                    return $"GDBH{next:0000}";
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"获取下一个工单编号失败: {ex.Message}");
                return null;
            }
        }

        protected override void OnFormClosing(FormClosingEventArgs e)
        {
            base.OnFormClosing(e);
        }
    }
}
